#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#include "lockgroup.hpp"
#include "LOG.hpp"
#include <string.h>
#include <string>
#include <unistd.h>
#include <pthread.h>
#include <sys/wait.h>
#include <functional>
#include "Socket.hpp"
#include "InetAddr.h"
using namespace std;


using func_t = function<string(const string&)>;

using io_service_t = function<void(socket_sptr fd,InetAddr client)>;


class Tcpsever;

class ThreadData
{
public:
    ThreadData(socket_sptr socket,InetAddr client,Tcpsever* self)
    :_socket(socket)
    ,_client(client)
    ,_self(self)
    {}

public:
    socket_sptr _socket;
    InetAddr _client;
    Tcpsever* _self;
};




class Tcpsever
{
public:
    Tcpsever(uint16_t port, io_service_t service) 
        : _addr("0", port)
        , _listensocket(std::make_unique<TcpSocket>())
        , _service(service)
        , _isrunning(false)
    {
        _listensocket->BuildListenSocket(_addr);
    }
    
    
    static void* handler(void* args)
    {
        pthread_detach(pthread_self());
        ThreadData* data = static_cast<ThreadData*>(args);
        data->_self->_service(data->_socket,data->_client);
        //处理完，关掉文件描述符
        close(data->_socket->sockfd());
        delete data;
        return nullptr;
    }

    void Loop()
    {
        // 4.不能直接接收数据，要先获取连接
        _isrunning = true;
        while (_isrunning)
        {
            InetAddr peeraddr;
            socket_sptr normalsock = _listensocket->AcceptSocket(&peeraddr);
            if(normalsock == nullptr) continue;
            //vesion 2:多线程
            pthread_t tid;
            ThreadData* data = new ThreadData(normalsock,InetAddr(peeraddr),this);
            pthread_create(&tid,nullptr,handler,data);
        }
        _isrunning = false;
    }
    ~Tcpsever()
    {

    }

private:
    socket_sptr _listensocket;
    bool _isrunning;
    InetAddr _addr;
    //上层业务
    func_t _func;
    io_service_t _service;
};